#ifndef _ZERO_CXX_ABIBASE_H
#define _ZERO_CXX_ABIBASE_H
#include "include/cxxstd.h"
#include "include/config.h"

namespace zero
{
struct Section
{
	ptr_t begin;
	ptr_t end;
};

typedef Section Elf;

typedef void* (*MallocHandle)(std::size_t);
typedef void (*FreeHandle)(void*);
typedef void (*Entry)(void);

/**
 * @class ABIBase
 * Note: os_allocator is used to allocate memory if ABIBase member function need memory.
 */
class ABIBase
{
	public:
		static ABIBase* create(const unsigned char*, MallocHandle, FreeHandle);
		static void push(ABIBase* base) {
			base->prev = last;
			last = base;
		}
		static ABIBase* pop() {
			if (last->prev != NULL) {
				ABIBase* tmp = last;
				last = last->prev;
				return tmp;
			}
			return NULL;
		}
		static ABIBase* top() {
			return last;
		}

		void load(void);
		void unload(void);
		bool include(ptr_t p) {
			return text.begin <= p && text.end > p;
		}
		ABIBase* getPrev() {
			return prev;
		}

	private:
		// ABIBase stack.
		static ABIBase* last;
		ABIBase* prev;

		// ELF.
		void paserELF(const unsigned char*);
		Elf elf;
		Section text, data, bss,
			ctors, dtors,
			rel, importedSym,
			typeinfo,
			unwindex, cxxex;

	public:
		Section exHeader;
		Entry codeEntry;

		bool pic;

		// new/delete handler.
		MallocHandle newHandler;
		FreeHandle deleteHandler;
};
}
#endif
